package ru.usu.gv.gui;

import ru.usu.gv.core.GraphCanvas;
import ru.usu.gv.core.GraphEngine;
import ru.usu.gv.core.I18nService;
import ru.usu.gv.core.ResourceLoader;
import ru.usu.gv.gui.actions.*;
import ru.usu.gv.gui.analysis.AnalysisPanel;
import ru.usu.gv.gui.dynamic.DynamicVisPanel;
import ru.usu.gv.gui.frames.CreateNewGraphFrame;
import ru.usu.gv.gui.frames.styles.EditStyleFrame;
import ru.usu.gv.styles.Style;
import ru.usu.gv.styles.StyleFacade;
import ru.usu.gv.uicomponents.UIEdge;
import ru.usu.gv.uicomponents.UIElementBase;
import ru.usu.gv.uicomponents.UIGraph;
import ru.usu.gv.uicomponents.UIUtilities;
import ru.usu.gv.uicomponents.UIVertex;
import ru.usu.gv.utils.Files;
import ru.usu.gv.utils.RandomUtilities;
import ru.usu.gv.utils.exports.ExportTool;
import ru.usu.gv.utils.exports.GraphExporter;
import ru.usu.gv.utils.imports.GraphImporter;
import ru.usu.gv.utils.imports.XmlParseException;
import ru.usu.gv.view.AddEdgePickingClient;

import javax.media.j3d.Transform3D;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.KeyStroke;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 @author Sergey Pupyrev 
 07.01.2007
 look at http://jug.org.ua/wiki/display/JavaAlmanac/Converting+a+KeyStroke+to+a+String
 */

public class GVActions
{
	private static final GVActions INSTANCE = new GVActions();

	private GVActions()
	{
		initialize();
	}

	public static GVActions getInstance()
	{
		return INSTANCE;
	}

	private Action fileNewAction;
	private Action addNodeAction;
	private Action addEdgeAction;
	private Action deleteAction;
	private Action stepForwardAction;
	private Action stepBackwardAction;
	private Action deselectAllAction;
	private Action selectAllAction;
	private Action invertSelectionAction;

	//private Action settingLauoutAction;

	//private int fileCounter = 0;

	private void initialize()
	{
		fileNewAction = new AbstractAction(I18nService.get("menu.new_file"))
		{
			public void actionPerformed(ActionEvent e)
			{
				ActionBase action = new DeleteGraphAction();
				action.execute();

				System.out.println("'New' Action performed");
			}
		};
		configAction(fileNewAction, "Create a new graph.", "control N", 'Н', "new.gif");

		addNodeAction = new AbstractAction(I18nService.get("menu.add_node"))
		{
			public void actionPerformed(ActionEvent e)
			{
				AddVertexAction action = new AddVertexAction(RandomUtilities.generateRandomPoint());
				action.execute();
			}
		};
		configAction(addNodeAction, I18nService.get("menu.add_node"), "alt A", 'z', "addvertex.png");

		addEdgeAction = new AbstractAction(I18nService.get("menu.add_edge"))
		{
			public void actionPerformed(ActionEvent e)
			{
				GraphEngine.getInstance().getPickListener().register(UIVertex.class, new AddEdgePickingClient());
				GraphEngine.getInstance().getPickListener().setPickedListLimit(2);
			}
		};
		configAction(addEdgeAction, I18nService.get("menu.add_edge"), "alt E", 'z', "addedge.png");

		deleteAction = new AbstractAction(I18nService.get("menu.delete"))
		{
			public void actionPerformed(ActionEvent e)
			{
				for (UIElementBase element : GraphEngine.getInstance().getPickListener().getPickedList())
				{
					if (element instanceof UIVertex)
						new DeleteVertexAction((UIVertex) element).execute();
					else if (element instanceof UIEdge)
						new DeleteEdgeAction((UIEdge) element).execute();
					else
						element.delete();
				}

				GraphEngine.getInstance().getPickListener().clearPickList();
			}
		};
		configAction(deleteAction, I18nService.get("menu.delete"), "DELETE", 'z', "delete.png");

		stepForwardAction = new AbstractAction(I18nService.get("menu.redo"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(stepForwardAction, I18nService.get("menu.redo"), "control Y", 'z', "redo.png");

		stepBackwardAction = new AbstractAction(I18nService.get("menu.undo"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(stepBackwardAction, I18nService.get("menu.undo"), "control Z", 'z', "undo.png");

		//selections
		selectAllAction = new AbstractAction(I18nService.get("menu.selectAll"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(selectAllAction, I18nService.get("menu.selectAll"), "control A", 'z', "");

		deselectAllAction = new AbstractAction(I18nService.get("menu.deselectAll"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(deselectAllAction, I18nService.get("menu.deselectAll"), "control U", 'z', "");

		invertSelectionAction = new AbstractAction(I18nService.get("menu.invert_selection"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(invertSelectionAction, I18nService.get("menu.invert_selection"), "control I", 'z', "");

	}

	private void configAction(Action a, String desc, String acc, char mn, String smallIcon)
	{
		a.putValue(Action.SHORT_DESCRIPTION, desc);
		a.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(acc));
		a.putValue(Action.MNEMONIC_KEY, new Integer(Character.getNumericValue(mn) + 55));
		if (smallIcon != null && smallIcon.length() > 0)
			a.putValue(Action.SMALL_ICON, ResourceLoader.loadImage("images/" + smallIcon));
	}

	public JMenu getFileMenu(final GVMenuBar menuBar)
	{
		JMenu fileMenu = new JMenu();
		fileMenu.setText(I18nService.get("menu.file"));

		//New
		fileMenu.add(fileNewAction);

		//Import
		Action importAction = new AbstractAction(I18nService.get("menu.open"))
		{
			public void actionPerformed(ActionEvent e)
			{
				String selectedFile = GUIUtilities.chooseOpenSaveFile(menuBar.getParent(), true);
				if (selectedFile != null)
				{
					try
					{
						AddGraphAction action = new AddGraphAction(GraphImporter.loadGraph(selectedFile));
						action.execute();
					}
					catch (Exception exc)
					{
						throw new RuntimeException(exc);
					}
				}
			}
		};
		configAction(importAction, I18nService.get("menu.open"), "control O", 'O', "open.gif");
		fileMenu.add(importAction);

		//Save
		Action exportAction = new AbstractAction(I18nService.get("menu.save"))
		{
			public void actionPerformed(ActionEvent e)
			{
				String selectedFile = GUIUtilities.chooseOpenSaveFile(menuBar.getParent(), false);
				if (selectedFile != null)
				{
					if (!selectedFile.endsWith(".gml"))
					{
						selectedFile = selectedFile.concat(".gml");
					}
					System.out.print("Saving file: " + selectedFile + "...");

					try
					{
						GraphExporter.saveGraph(GraphCanvas.getInstance().getCurrentGraph(), selectedFile);
						System.out.println("done");
					}
					catch (XmlParseException ex)
					{
						throw new RuntimeException(ex);
					}
				}
			}
		};
		configAction(exportAction, I18nService.get("menu.save"), "control S", 'z', "save.png");
		fileMenu.add(exportAction);

		//SaveAs
		Action exportAsAction = new AbstractAction(I18nService.get("menu.saveAs"))
		{
			public void actionPerformed(ActionEvent e)
			{
				//JFileChooser chooser = new JFileChooser(GUIUtilities.getLastDirectory());
				String fileName = GUIUtilities.chooseSaveAsFile(menuBar.getParent());

				if (fileName != null)
				{
					JFileChooser chooser = GUIUtilities.getSaveAsJFileChooser();
					//TODO: refactor it!
					if (chooser.getFileFilter() instanceof Files.JPEGFileFilter)
					{
						if (!fileName.endsWith(".jpg"))
							fileName += ".jpg";
						ExportTool.writeJPEG(fileName, 1.0f);
					}
					else if (chooser.getFileFilter() instanceof Files.PNGFileFilter)
					{
						if (!fileName.endsWith(".png"))
							fileName += ".png";
						ExportTool.writePNG(fileName, 1.0f);
					}
					else if (chooser.getFileFilter() instanceof Files.BMPFileFilter)
					{
						if (!fileName.endsWith(".bmp"))
							fileName += ".bmp";
						ExportTool.writeBMP(fileName, 1.0f);
					}
					else if (chooser.getFileFilter() instanceof Files.HTMLFileFilter)
					{
						if (!fileName.endsWith(".html"))
							fileName += ".html";
						ExportTool.writeHTML(fileName, 1.0f);
					}
					else if (chooser.getFileFilter() instanceof Files.PDFFileFilter)
					{
						if (!fileName.endsWith(".pdf"))
							fileName += ".pdf";
						ExportTool.writePDF(fileName, 1.0f);
					}
					else if (chooser.getFileFilter() instanceof Files.AVIFileFilter)
					{
						if (!fileName.endsWith(".avi"))
							fileName += ".avi";
						ExportTool.saveAVI(fileName);
					}
					else if (chooser.getFileFilter() instanceof Files.LJFileFilter)
					{
						if (!fileName.endsWith(".lj"))
							fileName += ".lj";
						GraphExporter.exportAsLJGraph(GraphCanvas.getInstance().getCurrentGraph(), fileName);
					}
					else if (chooser.getFileFilter() instanceof Files.DotFileFilter)
					{
						if (!fileName.endsWith(".dot"))
							fileName += ".dot";
						GraphExporter.exportToDot(GraphCanvas.getInstance().getCurrentGraph(), fileName);
					}
					else if (chooser.getFileFilter() instanceof Files.SVGFileFilter)
					{
						if (!fileName.endsWith(".svg"))
							fileName += ".svg";
						GraphExporter.exportToSvg(GraphCanvas.getInstance().getCurrentGraph(), fileName);
					}
				}
			}
		};
		configAction(exportAsAction, I18nService.get("menu.saveAs"), null, 'z', "saveas.png");
		fileMenu.add(exportAsAction);

		fileMenu.add(new JSeparator());

		//Print
		Action printAction = new AbstractAction(I18nService.get("menu.print"))
		{
			public void actionPerformed(ActionEvent e)
			{
				ExportTool.print(1.0f);
			}
		};
		configAction(printAction, I18nService.get("menu.print"), "control P", 'z', "print.png");
		fileMenu.add(printAction);

		fileMenu.add(new JSeparator());

		//eXit
		JMenuItem exitMenuItem = new JMenuItem();
		exitMenuItem.setText(I18nService.get("menu.exit"));
		exitMenuItem.setMnemonic('x');
		exitMenuItem.setAction(new AbstractAction(I18nService.get("menu.exit"))
		{
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});
		fileMenu.add(exitMenuItem);

		return fileMenu;
	}

	public JMenu getEditMenu()
	{
		JMenu menu = new JMenu();
		menu.setText(I18nService.get("menu.edit"));
		JMenuItem item = new JMenuItem(stepForwardAction);
		item.setEnabled(false);
		menu.add(item);
		item = new JMenuItem(stepBackwardAction);
		item.setEnabled(false);
		menu.add(item);
		menu.add(new JSeparator());

		menu.add(selectAllAction);
		menu.add(deselectAllAction);
		menu.add(invertSelectionAction);
		menu.add(new JSeparator());

		menu.add(addNodeAction);
		menu.add(addEdgeAction);
		menu.add(deleteAction);

		return menu;
	}

	public JMenu getStylesMenu()
	{
		JMenu menu = new JMenu();
		menu.setText(I18nService.get("menu.style"));
		Action newStyleAction = new AbstractAction(I18nService.get("menu.style.new"))
		{
			public void actionPerformed(ActionEvent e)
			{
				//new CreateStyleFrame().setVisible(true);
			}
		};
		configAction(newStyleAction, I18nService.get("menu.style.new"), "control shift N", 'z', "");
		menu.add(newStyleAction);

		Action editStyleAction = new AbstractAction(I18nService.get("menu.style.current"))
		{
			public void actionPerformed(ActionEvent e)
			{
				Style currentStyle = StyleFacade.getCurrentStyle();
				EditStyleFrame styleFrame = new EditStyleFrame(currentStyle);
				GUIUtilities.centralizeFrame(styleFrame);
				styleFrame.setVisible(true);
			}
		};
		configAction(editStyleAction, I18nService.get("menu.style.current"), "control shift T", 'z', "");
		menu.add(editStyleAction);

		Action applyStyleAction = new AbstractAction(I18nService.get("menu.style.apply"))
		{
			public void actionPerformed(ActionEvent e)
			{
				Style currentStyle = StyleFacade.getCurrentStyle();
				new ApplyStyleAction(currentStyle).execute();
			}
		};
		configAction(applyStyleAction, I18nService.get("menu.style.apply"), "control shift T", 'z', "");
		menu.add(applyStyleAction);
		return menu;
	}

	public JMenu getViewMenu()
	{
		JMenu menu = new JMenu();
		menu.setText(I18nService.get("menu.view"));

		Action zoomInAction = new AbstractAction(I18nService.get("menu.view.zoom_in"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIUtilities.scaleWindow(-2.5);
			}
		};
		configAction(zoomInAction, I18nService.get("menu.view.zoom_in"), "ADD", 'z', "zoom_in.png");
		menu.add(zoomInAction);

		Action zoomOutAction = new AbstractAction(I18nService.get("menu.view.zoom_out"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIUtilities.scaleWindow(2.5);
			}
		};
		configAction(zoomOutAction, I18nService.get("menu.view.zoom_out"), "SUBTRACT", 'z', "zoom_out.png");
		menu.add(zoomOutAction);

		Action zoomNormalAction = new AbstractAction("100%")
		{
			public void actionPerformed(ActionEvent e)
			{
				GraphCanvas.getInstance().getTransformGroup().setTransform(new Transform3D());
				GraphCanvas.getInstance().getUniverse().getViewingPlatform().setNominalViewingTransform();
			}
		};
		configAction(zoomNormalAction, "100%", "ENTER", 'z', "zoom_1_1.png");
		menu.add(zoomNormalAction);
		menu.add(new JSeparator());

		Action zoomLocalAction = new AbstractAction(I18nService.get("menu.view.zoom_local"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(zoomLocalAction, I18nService.get("menu.view.zoom_local"), "DIVIDE", 'z', "zoom_local.png");
		menu.add(zoomLocalAction);

		Action zoomFitAction = new AbstractAction(I18nService.get("menu.view.zoom_fit"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIUtilities.fitGraphIntoWindow();
			}
		};
		configAction(zoomFitAction, I18nService.get("menu.view.zoom_fit"), "MULTIPLY", 'z', "zoom_fit.png");
		menu.add(zoomFitAction);
		//zoomFitAction.actionPerformed(null);
		menu.add(new JSeparator());

		JCheckBoxMenuItem showAxisCheckBoxMenuItem = new JCheckBoxMenuItem();
		showAxisCheckBoxMenuItem.setText(I18nService.get("menu.view.axis"));
		showAxisCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				JCheckBoxMenuItem checkBox = (JCheckBoxMenuItem) e.getSource();
				GraphCanvas.getInstance().setAxisVisible(checkBox.isSelected());
			}
		});
		menu.add(showAxisCheckBoxMenuItem);

		JCheckBoxMenuItem autoRotateCheckBoxMenuItem = new JCheckBoxMenuItem();
		autoRotateCheckBoxMenuItem.setText(I18nService.get("menu.view.rotate"));
		autoRotateCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				GraphEngine.getInstance().toggleRotator();
			}
		});
		menu.add(autoRotateCheckBoxMenuItem);

		final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem(I18nService.get("menu.view.edit"));
		checkBox.setAccelerator(KeyStroke.getKeyStroke("control R"));
		checkBox.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				//TODO: move to GraphEngine???
				boolean enabled = false;
				if (checkBox.isSelected())
				{
					enabled = true;
					GraphEngine.getInstance().getPickListener().disableAllClients();
					GraphEngine.getInstance().getPickListener().setPickedListLimit(0);
				}
				else
				{
					enabled = false;
					GraphEngine.getInstance().getPickListener().enableAllClients();
					GraphEngine.getInstance().getPickListener().setPickedListLimit(1);
				}
				GraphEngine.getInstance().setEnableGraphEdit(enabled);
			}
		});
		menu.add(checkBox);
		checkBox.setSelected(true);
		checkBox.getActionListeners()[0].actionPerformed(null);

		JCheckBoxMenuItem showAnalysisCheckBoxMenuItem = new JCheckBoxMenuItem();
		showAnalysisCheckBoxMenuItem.setText(I18nService.get("menu.view.analysis"));
		showAnalysisCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				AnalysisPanel.getInstance().changeVisibleState();
			}
		});
		menu.add(showAnalysisCheckBoxMenuItem);

		JCheckBoxMenuItem showDynamicCheckBoxMenuItem = new JCheckBoxMenuItem();
		showDynamicCheckBoxMenuItem.setText(I18nService.get("menu.view.dynamic"));
		showDynamicCheckBoxMenuItem.setAccelerator(KeyStroke.getKeyStroke("control alt D"));
		showDynamicCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				DynamicVisPanel.getInstance().changeVisibleState();
			}
		});
		menu.add(showDynamicCheckBoxMenuItem);

		final JCheckBoxMenuItem _3DModeMenuItem = new JCheckBoxMenuItem(I18nService.get("menu.view.3D"), StyleFacade.is3D());
		_3DModeMenuItem.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				if (_3DModeMenuItem.isSelected())
				{
					System.out.println("switching to 3D mode");
					
					StyleFacade.set3D(true);
					GraphEngine.getInstance().getMouseRotationBehavior().setEnable(true);
				}
				else
				{
					System.out.println("switching to 2D mode");
					StyleFacade.set3D(false);
					
					UIGraph uiGraph = GraphCanvas.getInstance().getCurrentGraph();
					for (UIVertex v : uiGraph.getVertexes())
						v.getPosition().z = 0;
					uiGraph.draw();
					
					GraphEngine.getInstance().getMouseRotationBehavior().setEnable(false);
					GraphCanvas.getInstance().getTransformGroup().setTransform(new Transform3D());
				}
			}
		});
		menu.add(_3DModeMenuItem);
		_3DModeMenuItem.getActionListeners()[0].actionPerformed(null);

		return menu;
	}

	public JMenu getLayoutMenu()
	{
		JMenu menu = new JMenu();
		menu.setText(I18nService.get("menu.layout"));
		for (Action action : new GVLayoutActions().getLayoutActions())
			if (action != null)
				menu.add(action);
			else
				menu.add(new JSeparator());

		JMenu mdsActionsMenu = new JMenu("MDS");
		for (Action action : new GVLayoutActions().getMDSLayoutActions())
			mdsActionsMenu.add(action);
		menu.add(mdsActionsMenu);

		JMenu spectralActionsMenu = new JMenu("Spectral layout");
		for (Action action : new GVLayoutActions().getSpectralLayoutActions())
			spectralActionsMenu.add(action);
		menu.add(spectralActionsMenu);

		JMenu rwActionsMenu = new JMenu("Random walk");
		for (Action action : new GVLayoutActions().getRandomWalkLayoutActions())
			rwActionsMenu.add(action);
		menu.add(rwActionsMenu);

		return menu;
	}

	public JMenu getToolsMenu()
	{
		JMenu menu = new JMenu();
		menu.setText(I18nService.get("menu.tools"));

		Action createNewGraphAction = new AbstractAction(I18nService.get("menu.tools.new_graph"))
		{
			private CreateNewGraphFrame frame;

			public void actionPerformed(ActionEvent e)
			{
				if (frame == null)
					frame = new CreateNewGraphFrame();

				frame.setVisible(true);
			}
		};
		menu.add(createNewGraphAction);

		Action centralizeGraphAction = new AbstractAction(I18nService.get("menu.tools.centrilize_graph"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIUtilities.centralizeGraph();
			}
		};
		menu.add(centralizeGraphAction);

		Action scaleGraphAction = new AbstractAction(I18nService.get("menu.tools.scale_graph"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIUtilities.scaleGraph();
			}
		};
		menu.add(scaleGraphAction);

		Action restificationAction = new AbstractAction(I18nService.get("menu.tools.restificate"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIGraph currentGraph = GraphCanvas.getInstance().getCurrentGraph();
				for (UIEdge edge : currentGraph.getEdges())
					edge.getViewItem().rectificate();

				currentGraph.draw();
			}
		};
		menu.add(restificationAction);

		//Show vertex labels
		final String showActionName = "showVertexLabels";
		final Action showVertexLabelAction = new AbstractAction("")
		{
			public void actionPerformed(ActionEvent e)
			{
				if (getValue(showActionName).equals("false"))
				{
					putValue(showActionName, "true");
					putValue(Action.NAME, I18nService.get("menu.tools.show_labels"));
					new ShowVertexLabelsAction(false).execute();
				}
				else
				{
					putValue(showActionName, "false");
					putValue(Action.NAME, I18nService.get("menu.tools.hide_labels"));
					new ShowVertexLabelsAction(true).execute();
				}
			}
		};
		configAction(showVertexLabelAction, "", "control alt L", 'z', "");
		menu.add(showVertexLabelAction);
		if (StyleFacade.isShowVertexLabel())
		{
			showVertexLabelAction.putValue(showActionName, "false");
			showVertexLabelAction.putValue(Action.NAME, I18nService.get("menu.tools.hide_labels"));
		}
		else
		{
			showVertexLabelAction.putValue(showActionName, "true");
			showVertexLabelAction.putValue(Action.NAME, I18nService.get("menu.tools.show_labels"));
		}

		//Show edges
		final String showEdgesActionName = "showEdges";
		final Action showEdgesAction = new AbstractAction("")
		{
			public void actionPerformed(ActionEvent e)
			{
				Object value = getValue(showEdgesActionName);
				if (value == null || value.equals("false"))
				{
					putValue(showEdgesActionName, "true");
					putValue(Action.NAME, I18nService.get("menu.tools.show_edges"));
					new ShowEdgesAction(false).execute();
				}
				else
				{
					putValue(showEdgesActionName, "false");
					putValue(Action.NAME, I18nService.get("menu.tools.hide_edges"));
					new ShowEdgesAction(true).execute();
				}
			}
		};
		configAction(showEdgesAction, "", "control alt E", 'z', "");
		menu.add(showEdgesAction);
		if (StyleFacade.isShowEdges())
		{
			showEdgesAction.putValue(showEdgesActionName, "false");
			showEdgesAction.putValue(Action.NAME, I18nService.get("menu.tools.hide_edges"));
		}
		else
		{
			showEdgesAction.putValue(showEdgesActionName, "true");
			showEdgesAction.putValue(Action.NAME, I18nService.get("menu.tools.show_edges"));
		}

		Action simplifyGraphAction = new AbstractAction(I18nService.get("menu.tools.simplify_graph"))
		{
			public void actionPerformed(ActionEvent e)
			{
				new SimplifyGraphAction().execute();
			}
		};
		menu.add(simplifyGraphAction);

		Action edgeRoutingAction = new AbstractAction(I18nService.get("menu.tools.edge_routing"))
		{
			public void actionPerformed(ActionEvent e)
			{
				new EdgeRoutingAction().execute();
			}
		};
		configAction(edgeRoutingAction, "", "control alt R", 'z', "");
		menu.add(edgeRoutingAction);

		Action twoDimensionsAction = new AbstractAction(I18nService.get("menu.tools.project_2d"))
		{
			public void actionPerformed(ActionEvent e)
			{
				UIGraph uiGraph = GraphCanvas.getInstance().getCurrentGraph();
				for (UIVertex v : uiGraph.getVertexes())
					v.getPosition().z = 0;
				uiGraph.draw();
			}
		};
		menu.add(twoDimensionsAction);

		return menu;
	}

	public JMenu getHelpMenu()
	{
		JMenu menu = new JMenu();
		menu.setText(I18nService.get("menu.help"));

		Action helpAction = new AbstractAction(I18nService.get("menu.help.content"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(helpAction, I18nService.get("menu.help.content"), "F1", 'z', "about.png");
		menu.add(helpAction);

		Action aboutAction = new AbstractAction(I18nService.get("menu.help.about"))
		{
			public void actionPerformed(ActionEvent e)
			{
			}
		};
		configAction(aboutAction, I18nService.get("menu.help.about"), "control F1", 'z', "help.png");
		menu.add(aboutAction);

		return menu;
	}

}
